#include "stack.h"

#include "mem.h"
#include "assert.h"

#define T Stack_T

struct T {
    int count;
    struct elem {
        void *x;
        struct elem *link;
    } *head;
};

T Stack_new()
{
    T stk;
    NEW(stk);
    stk->count = 0;
    stk->head = NULL;
    return stk;
}

int Stack_empty(T stk)
{
    assert(stk);
    return stk->count == 0;
}

void Stack_push(T stk, void *x)
{
    assert(stk);

    struct elem *p;
    NEW(p);
    p->x = x;
    p->link = stk->head;

    stk->head = p;
    stk->count++;
}

void* Stack_pop(T stk)
{
    assert(stk);
    assert(stk->count > 0);

    struct elem *p = stk->head;
    stk->head = p->link;
    stk->count--;

    void *x = p->x;
    FREE(p);
    return x;
}

void Stack_free(T *stk)
{
    assert(stk && *stk);

    struct elem *p, *q;
    for (p = (*stk)->head; p; p = q) {
        q = p->link;
        FREE(p);
    }
    FREE(*stk);
}

